
var mjs = function () {

  var modulesPath = '';

  function normalize(script) {
     if (script.indexOf('_module_') == 0) { return modulesPath + script; }
     return script;
  }
  
  function add2collection(array, item) {
    for (i = 0; i < array.length; i++) {
      if (array[i] == item) { return; }
    }
    array.push(item);
  }
  
  function onloadTask (observedScript, callback) {
     setTimeout(
                function () {  
                        s = document.getElementsByTagName('script');  
                        for (var i = 0; i < s.length; i ++) {
                            var src = s[i].src;
                            if (src.indexOf(observedScript)) {
                                callback(observedScript);
                                return;
                            }
                        }
                        new onloadTask (observedScript, callback);
                }, 1000);
  }
  
  var status = {
      
      loaded: new Array(),
      
      pending: new Array(),
      
      meta : new Object(),
      
      isLoaded: function(script) {
          for (i = 0;i<mjs.status.loaded.length;i++) {
            if (mjs.status.loaded[i] == script) {
              return true;
            }
          }
          return false;
      },
      
      isPending: function(script) {
          for (i = 0;i < mjs.status.pending.length;i++) {
            if (mjs.status.pending[i] == script) {
              return true;
            }
          }
          return false;
      },
      
      addRequires : function (script, reqScripts, callback, argument) {
          if (mjs.status.meta[script] == null) {
              mjs.status.meta[script] = { rq: reqScripts, callback:  [ callback ], argument: [ argument ] };
          } else { 
              mjs.status.meta[script].callback.push(callback);
              mjs.status.meta[script].argument.push(argument);
          }
          for (i = 0; i < reqScripts.length; i++) {
            add2collection(mjs.status.meta[script].rq, reqScripts[i]);
          }
      },
      
      pend : function(script) {
          if (mjs.status.isLoaded(script)) {
              return;
          }
          if (!mjs.status.isPending(script)) {
             mjs.status.pending.push(script);
          }
      },
      
      setLoaded: function(script) {
         mjs.status.loaded.push(script);
         for (var i = 0; i < mjs.status.pending.length; i++) {
             if (mjs.status.pending[i] == script) {
                 mjs.status.pending[i] = null;
             }
         }
      }
  };
  

  var __object__ = 
    {  
      status: status,
      
      load: function(script, req_scripts, __callback, argument) {

         var script = normalize(script);
         
         if (mjs.status.isLoaded(script) || mjs.status.isPending(script)) {
            mjs.status.addRequires(script, req_scripts, __callback, argument);
            return;
         }
         if (typeof req_scripts != 'undefined') {
             for (var i = 0; i < req_scripts.length; i++) {
                req_scripts[i] = normalize(req_scripts[i]);
             }
             mjs.status.pend(script);
             mjs.status.addRequires(script, req_scripts, __callback, argument);
            for (var i = 0; i < mjs.status.meta[script].rq.length; i++) {
                mjs.load(mjs.status.meta[script].rq[i]);
            }
         } else {
              mjs.status.pend(script, [ ], function() { }, null);
              mjs.status.addRequires(script, [ ], function() { }, null);
         }
         LazyLoad.loadOnce(script);
         new onloadTask(script, 
                 function (script) {
                   //alert('loaded ' + script);
                 try {
                   if (mjs.status.isLoaded(script)) {
                      return;
                   }
                 mjs.status.setLoaded(script);
                 } catch(e) { alert('ex=' + e); }
              });
         /* + '?' + Math.floor(Math.random()*110030)
         
              function (script) {
                 alert('loaded ' + script);
                 try {
                   if (mjs.status.isLoaded(script)) {
                      return;
                   }
                 mjs.status.setLoaded(script);
                 } catch(e) { alert('ex=' + e); }
              },
              script);*/
              
      },
      
      // call from JS files
      require: function(script, req_scripts, __callback) {
         var script = normalize(script);
         for (var i = 0; i < req_scripts.length; i++) {
            req_scripts[i] = normalize(req_scripts[i]);
         }
         mjs.status.addRequires(script, req_scripts, __callback, null);
         for (var i = 0; i < req_scripts.length; i++) {
            req_scripts[i] = normalize(req_scripts[i]);
            mjs.load(mjs.status.meta[script].rq[i]);
         }
      }
      ,
      setModulesPath: function(path) {
          modulesPath = path;
      },
      
      check : function() {
          //alert('check');
          for (var i = 0; i < mjs.status.loaded.length; i++) {
              var allRequiredScriptsLoaded = true;
              var script = mjs.status.loaded[i];
              for (var j = 0; j < mjs.status.meta[script].rq.length; j++) {
                  var rq = mjs.status.meta[script].rq[j];
                  if (! mjs.status.isLoaded(rq)) {
                      allRequiredScriptsLoaded = false;
                      break;
                  }
                  // check for all callbacks must be called
                  var callbacks = mjs.status.meta[rq].callback;
                  for (var cc = 0; cc < callbacks.length; cc++) {
                      if (callbacks[cc] != null) {
                        allRequiredScriptsLoaded = false;
                        break;
                      }
                  }
              }
              var callbacks = mjs.status.meta[script].callback;
              if(allRequiredScriptsLoaded && callbacks.length > 0) {
                  for (var k = 0; k < callbacks.length; k++) {
                    if (callbacks[k] != null) {
                        var arguments = mjs.status.meta[script].argument;
                        for (var aa = 0; aa < arguments.length; aa++) {
                            if (arguments[aa] != null) {
                                callbacks[k](arguments[aa]);
                            }
                        }
                        callbacks[k] = null;
                    }
                  }
                  
                  for (var aa = 0; aa < arguments.length; aa++) {
                     arguments[aa] = null;
                  }    
              }
          } 
          setTimeout(mjs.check, 100);
      },
      
      initialize: function() {
         var components = new YAHOO.util.Element(document.body).getElementsByClassName('component');
         for (var i = 0; i < components.length; i++) {
            components[i].onclick(components[i]);
         }
      }
    };
  return __object__;
}();

YAHOO.util.Event.on(window, 'load', mjs.initialize);
setTimeout(mjs.check, 100);
